//+------+ //|BollTrade //+------+ #property copyright "Ron Thompson" #property link "http://www.lightpatch.com/forex" //3c1 - updated logwrite to latest version with dates - no change //3c1 - changed iBands to MA plus/minus Deviation - no change //3c1 - removed all equity statistics - no change //3c1 - lot increase always active (uses MAX_LOT) - no change //3c1 - removed CurrentBasket - no change //3c1 - removed OpenOrdersBUY & SELL tracking - no change //3c1 - added Margin requirement - no change //3c1 - corrected all the order open code - no change //3c1 - added CloseBuy & Sell to correct errors - no change //3c1 - removed OneOrderOnly - no change // At this point, this is as pure and error-free version of BollTrader // that you can have. The next step will be to integrate everything // from the news avoidance system. On to v03c2 // user input extern double StartingBalance= 10000; // lot size control during LotIncrease extern double MinFreeMarginPct= 25.0; // margin available before trading extern double ProfitMade = 8; // how much money do you expect to make extern double LossLimit = 35; // how much loss can you tolorate extern double BDistance = 14; // plus how much extern int BPeriod = 15; // Bollinger period extern int Deviation = 2.0; // Bollinger deviation // non-external flag settings int Slippage=2; // how many pips of slippage can you tolorate bool KillLogging=false; // turn off all logging bool logging=true; // log data or not bool logerrs=true; // log errors or not bool logtick=false; // log tick data while orders open (or not) // naming and numbering int MagicNumber = 200607121116; // allows multiple experts to trade on same account string TradeComment = "_bolltrade_v03c1.txt"; // Bar handling datetime bartime=0; // used to determine when a bar has moved int bartick=0; // number of times bars have moved // Trade control & statistics double Lots; // size of trades double LotResolution=2; // lot increase increment 1=0.1 2=0.01 bool TradeAllowed=true; // used to manage trades int maxOrders; // statistic for maximum numbers or orders open at one time int L2L=10; // real to server difference for order masking // order loop control and limit int loopcount; int maxloop=25; // used for verbose error logging #include //+-------------+ //| Custom init | //|-------------+ // Called ONCE when EA is added to chart or recompiled int init() { Lots=AccountBalance()/StartingBalance; logwrite(TradeComment,"LotIncrease ACTIVE Account balance="+AccountBalance()+" Lots="+Lots+" StartingBalance="+StartingBalance); logwrite(TradeComment,"Init Complete"); Comment(" "); } //+----------------+ //| Custom DE-init | //+----------------+ // Called ONCE when EA is removed from chart int deinit() { // always indicate deinit statistics logwrite(TradeComment,"MAX number of orders "+maxOrders); logwrite(TradeComment,"DE-Init Complete"); Comment(" "); } //+-----------+ //| Main | //+-----------+ // Called EACH TICK and each Bar[] int start() { int cnt=0; int gle=0; int ticket=0; int OrdersPerSymbol=0; // stoploss and takeprofit and close control double SL=0; double TP=0; double CurrentProfit=0; // direction control bool BUYme=false; bool SELLme=false; // bar counting if(bartime!=Time[0]) { bartime=Time[0]; bartick++; } // Lot increasement based on AccountBalance when expert is started // this will trade 1.0, then 1.1, then 1.2 etc as account balance grows // or 0.9 then 0.8 then 0.7 as account balance shrinks Lots=NormalizeDouble(AccountBalance()/StartingBalance,LotResolution); if( Lots>MarketInfo(Symbol(),MODE_MAXLOT) ) Lots=MarketInfo(Symbol(),MODE_MAXLOT); OrdersPerSymbol=0; for(cnt=OrdersTotal();cnt>=0;cnt--) { OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES); if( OrderSymbol()==Symbol() && OrderMagicNumber()==MagicNumber) { OrdersPerSymbol++; } } if(OrdersPerSymbol==0) TradeAllowed=true; // keep some statistics if(OrdersPerSymbol>maxOrders) maxOrders=OrdersPerSymbol; //+-----------------------------+ //| Insert your indicator here | //| And set either BUYme or | //| SELLme true to place orders | //+-----------------------------+ double ma = iMA(Symbol(),0,BPeriod,0,MODE_SMA,PRICE_OPEN,0); double stddev = iStdDev(Symbol(),0,BPeriod,0,MODE_SMA,PRICE_OPEN,0); double bup = ma+(Deviation*stddev); double bdn = ma-(Deviation*stddev); if(Close[0]>bup+(BDistance*Point)) SELLme=true; if(Close[0]maxloop) break; }//while }//BUYme //ENTRY SHORT (sell, Bid) if( OrdersPerSymbol==0 && TradeAllowed && SELLme ) { while(true) { if( AccountFreeMargin()< (AccountBalance()*(MinFreeMarginPct/100)) ) { if(logging) logwrite(TradeComment,"Your BUY equity is too low to trade"); break; } if(LossLimit ==0) SL=0; else SL=Bid+((LossLimit+L2L)*Point ); if(ProfitMade==0) TP=0; else TP=Bid-((ProfitMade+L2L)*Point ); ticket=OrderSend(Symbol(),OP_SELL,Lots,Bid,Slippage,SL,TP,TradeComment,MagicNumber,Red); gle=GetLastError(); if(gle==0) { if(logging) logwrite(TradeComment,"SELL Ticket="+ticket+" bup="+bup+" Bid="+Bid+" Lots="+Lots+" SL="+SL+" TP="+TP); TradeAllowed=false; break; } else { if(logerrs) logwrite(TradeComment,"-----ERROR----- opening SELL order: Lots="+Lots+" SL="+SL+" TP="+TP+" Bid="+Bid+" Ask="+Ask+" ticket="+ticket+" Err="+gle+" "+ErrorDescription(gle)); } RefreshRates(); Sleep(500); loopcount++; if(loopcount>maxloop) break; }//while }//SELLme // // Order Management // for(cnt=OrdersTotal();cnt>=0;cnt--) { OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES); if( OrderSymbol()==Symbol() && OrderMagicNumber()==MagicNumber ) { if(OrderType()==OP_BUY) { CurrentProfit=Bid-OrderOpenPrice() ; if(logtick) logwrite(TradeComment,"BUY CurrentProfit="+CurrentProfit/Point); // Did we make a profit or loss if(ProfitMade>0 && CurrentProfit>=(ProfitMade*Point)) CloseBuy("PROFIT"); if( LossLimit>0 && CurrentProfit<=(LossLimit*(-1)*Point) ) CloseBuy("LOSS"); } //if BUY if(OrderType()==OP_SELL) { CurrentProfit=OrderOpenPrice()-Ask; if(logtick) logwrite(TradeComment,"SELL CurrentProfit="+CurrentProfit/Point); // Did we make a profit or loss if( ProfitMade>0 && CurrentProfit>=(ProfitMade*Point) ) CloseSell("PROFIT"); if( LossLimit>0 && CurrentProfit<=(LossLimit*(-1)*Point) ) CloseSell("LOSS"); } //if SELL } // if(OrderSymbol) } // for } // start() void logwrite (string filename, string mydata) { int myhandle; string gregorian=TimeToStr(CurTime(),TIME_DATE|TIME_SECONDS); // don't log anything if testing or if user doesn't want it //if(IsTesting()) return(0); //if(KillLogging) return(0); //Print(mydata); myhandle=FileOpen(Symbol()+"_"+filename, FILE_CSV|FILE_WRITE|FILE_READ, ";"); if(myhandle>0) { FileSeek(myhandle,0,SEEK_END); FileWrite(myhandle, mydata+" "+gregorian); FileClose(myhandle); } } void CloseBuy (string myInfo) { int gle; int cnt; int OrdersPerSymbol; int loopcount=0; string bTK=" Ticket="+OrderTicket(); string bSL=" SL="+OrderStopLoss(); string bTP=" TP="+OrderTakeProfit(); string bPM; string bLL; string bER; bPM=" PM="+ProfitMade; bLL=" LL="+LossLimit; while(true) { OrderClose(OrderTicket(),OrderLots(),Bid,Slippage,White); gle=GetLastError(); bER=" error="+gle+" "+ErrorDescription(gle); if(gle==0) { if(logging) logwrite(TradeComment,"CLOSE BUY "+myInfo+ bTK + bSL + bTP + bPM + bLL); break; } else { if(logerrs) logwrite(TradeComment,"-----ERROR----- CLOSE BUY "+myInfo+ bER +" Bid="+Bid+ bTK + bSL + bTP + bPM + bLL); RefreshRates(); Sleep(500); } // sometimes an order close is delayed, or a gap jumps to the LL2SL on the server // This keeps a server-closed order from hanging here OrdersPerSymbol=0; for(cnt=OrdersTotal();cnt>=0;cnt--) { OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES); if( OrderSymbol()==Symbol() && OrderMagicNumber()==MagicNumber) OrdersPerSymbol++; } if(OrdersPerSymbol==0) break; loopcount++; if(loopcount>maxloop) break; }//while } void CloseSell (string myInfo) { int gle; int cnt; int OrdersPerSymbol; int loopcount=0; string sTK=" Ticket="+OrderTicket(); string sSL=" SL="+OrderStopLoss(); string sTP=" TP="+OrderTakeProfit(); string sPM; string sLL; string sER; sPM=" PM="+ProfitMade; sLL=" LL="+LossLimit; while(true) { OrderClose(OrderTicket(),OrderLots(),Ask,Slippage,Red); gle=GetLastError(); sER=" error="+gle+" "+ErrorDescription(gle); if(gle==0) { if(logging) logwrite(TradeComment,"CLOSE SELL "+myInfo + sTK + sSL + sTP + sPM + sLL); break; } else { if(logerrs) logwrite(TradeComment,"-----ERROR----- CLOSE SELL "+myInfo+ sER +" Ask="+Ask+ sTK + sSL + sTP + sPM + sLL); RefreshRates(); Sleep(500); } // sometimes an order close is delayed, or a gap jumps to the LL2SL on the server // This keeps a server-closed order from hanging here OrdersPerSymbol=0; for(cnt=OrdersTotal();cnt>=0;cnt--) { OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES); if( OrderSymbol()==Symbol() && OrderMagicNumber()==MagicNumber) OrdersPerSymbol++; } if(OrdersPerSymbol==0) break; loopcount++; if(loopcount>maxloop) break; }//while }